﻿// Copyright 2012 TIGERLIHAO.COM All Rights Reserved.

/**
 * @fileoverview Description of file, its uses and information
 * about its dependencies.
 * @author user@google.com (Firstname Lastname)
 */

var tigerlihao = {};
tigerlihao.cubic = {};
/**
 * Cubic class, initialized with an optional value.
 * @param {Object=} opt_config Configuration object (optional).
 * @constructor
 */
tigerlihao.cubic.Cubic = function (opt_config) {
  opt_config = opt_config || {};
  this.faces = opt_config.faces || [];
  this.temp = [];
  this.cubeinit = false;
  this.solution = "";
};
/**
 * Set value of face at position (x,y,z).
 * @param {number} x Coordinate X of face.
 * @param {number} y Coordinate Y of face.
 * @param {number} z Coordinate Z of face.
 * @param {number} value Value of face.
 */
tigerlihao.cubic.Cubic.prototype.setFace = function (x, y, z, value) {
  this.faces[x * 25 + y * 5 + z] = value;
};
/**
 * Get value of face at position (x,y,z).
 * @param {number} x Coordinate X of face.
 * @param {number} y Coordinate Y of face.
 * @param {number} z Coordinate Z of face.
 * @return {number} Value of face.
 */
tigerlihao.cubic.Cubic.prototype.getFace = function (x, y, z) {
  return this.faces[x * 25 + y * 5 + z];
};
/**
 * Create default (solved) cube
 */
tigerlihao.cubic.Cubic.prototype.reset = function () {
  for (var i = 0; i < 5 * 5 * 5; i++) {
    this.faces[i] = 0;
  }
  for (var i = 1; i <= 3; i++) {
    for (var j = 1; j <= 3; j++) {
      this.setFace(i, j, 0, 1); //Front  Red
      this.setFace(i, j, 4, 2); //Back Orange
      this.setFace(0, i, j, 3); //Left White
      this.setFace(4, i, j, 4); //Right Yellow
      this.setFace(i, 0, j, 5); //Down Green
      this.setFace(i, 4, j, 6); //Up Blue
    }
  }
  this.cubeinit = true;
};
/**
 * Create a temp cube of curent cube.
 * @private
 */
tigerlihao.cubic.Cubic.prototype.creatTemp = function () {
  this.temp = this.faces.concat();
};
/**
 * Rotate cube by axis X.
 * @param {Array<number>} levels Level ids.
 * @param {boolean} clockwise Clockwise or not.
 */
 tigerlihao.cubic.Cubic.prototype.rotateX = function (levels, clockwise) {
  var x, y, z,
    l = levels.length,
    setValue = clockwise ? function (c, x, y, z, v) {
        c.setFace(x, z, 4 - y, v);
      } : function (c, x, y, z, v) {
        c.setFace(x, 4 - z, y, v);
      };
  this.creatTemp();
  for (var i = 0; i < l; i++) {
    x = levels[i];
    for (var y = 0; y < 5; y++) {
      for (var z = 0; z < 5; z++) {
        var v = this.temp[x * 25 + y * 5 + z];
        if (v) {
          setValue(this, x, y, z, v);
        }
      }
    }
  }
};
/**
 * Rotate cube by axis Y.
 * @param {Array<number>} levels Level ids.
 * @param {boolean} clockwise Clockwise or not.
 */
tigerlihao.cubic.Cubic.prototype.rotateY = function (levels, clockwise) {
  var x, y, z,
    l = levels.length,
    setValue = clockwise ? function (c, x, y, z, v) {
        c.setFace(4 - z, y, x, v);
      } : function (c, x, y, z, v) {
        c.setFace(z, y, 4 - x, v);
      };
  this.creatTemp();
  for (var i = 0; i < l; i++) {
    y = levels[i];
    for (var z = 0; z < 5; z++) {
      for (var x = 0; x < 5; x++) {
        var v = this.temp[x * 25 + y * 5 + z];
        if (v) {
          setValue(this, x, y, z, v);
        }
      }
    }
  }
};
/**
 * Rotate cube by axis Z.
 * @param {Array<number>} levels Level ids.
 * @param {boolean} clockwise Clockwise or not.
 */
tigerlihao.cubic.Cubic.prototype.rotateZ = function (levels, clockwise) {
  var x, y, z,
    l = levels.length,
    setValue = clockwise ? function (c, x, y, z, v) {
        c.setFace(y, 4 - x, z, v);
      } : function (c, x, y, z, v) {
        c.setFace(4 - y, x, z, v);
      };
  this.creatTemp();
  for (var i = 0; i < l; i++) {
    z = levels[i];
    for (var x = 0; x < 5; x++) {
      for (var y = 0; y < 5; y++) {
        var v = this.temp[x * 25 + y * 5 + z];
        if (v) {
          setValue(this, x, y, z, v);
        }
      }
    }
  }
};
/**
 * Out put the cube.
 */
tigerlihao.cubic.Cubic.prototype.toString = function () {
  var s = '\n';
  s += '      ' + this.getFace(1, 4, 3) + ' ' + this.getFace(2, 4, 3) + ' ' + this.getFace(3, 4, 3) + '\n';
  s += '      ' + this.getFace(1, 4, 2) + ' ' + this.getFace(2, 4, 2) + ' ' + this.getFace(3, 4, 2) + '\n';
  s += '      ' + this.getFace(1, 4, 1) + ' ' + this.getFace(2, 4, 1) + ' ' + this.getFace(3, 4, 1) + '\n';
  s += this.getFace(0, 3, 3) + ' ' + this.getFace(0, 3, 2) + ' ' + this.getFace(0, 3, 1) + ' ';
  s += this.getFace(1, 3, 0) + ' ' + this.getFace(2, 3, 0) + ' ' + this.getFace(3, 3, 0) + ' ';
  s += this.getFace(4, 3, 1) + ' ' + this.getFace(4, 3, 2) + ' ' + this.getFace(4, 3, 3) + ' ';
  s += this.getFace(3, 3, 4) + ' ' + this.getFace(2, 3, 4) + ' ' + this.getFace(1, 3, 4) + '\n';
  s += this.getFace(0, 2, 3) + ' ' + this.getFace(0, 2, 2) + ' ' + this.getFace(0, 2, 1) + ' ';
  s += this.getFace(1, 2, 0) + ' ' + this.getFace(2, 2, 0) + ' ' + this.getFace(3, 2, 0) + ' ';
  s += this.getFace(4, 2, 1) + ' ' + this.getFace(4, 2, 2) + ' ' + this.getFace(4, 2, 3) + ' ';
  s += this.getFace(3, 2, 4) + ' ' + this.getFace(2, 2, 4) + ' ' + this.getFace(1, 2, 4) + '\n';
  s += this.getFace(0, 1, 3) + ' ' + this.getFace(0, 1, 2) + ' ' + this.getFace(0, 1, 1) + ' ';
  s += this.getFace(1, 1, 0) + ' ' + this.getFace(2, 1, 0) + ' ' + this.getFace(3, 1, 0) + ' ';
  s += this.getFace(4, 1, 1) + ' ' + this.getFace(4, 1, 2) + ' ' + this.getFace(4, 1, 3) + ' ';
  s += this.getFace(3, 1, 4) + ' ' + this.getFace(2, 1, 4) + ' ' + this.getFace(1, 1, 4) + '\n';
  s += '      ' + this.getFace(1, 0, 1) + ' ' + this.getFace(2, 0, 1) + ' ' + this.getFace(3, 0, 1) + '\n';
  s += '      ' + this.getFace(1, 0, 2) + ' ' + this.getFace(2, 0, 2) + ' ' + this.getFace(3, 0, 2) + '\n';
  s += '      ' + this.getFace(1, 0, 3) + ' ' + this.getFace(2, 0, 3) + ' ' + this.getFace(3, 0, 3) + '\n';
  return s;
}
